//
//  String+Extension.swift
//  Swift-Tools
//
//  Created by 深圳-周星驰 on 2020/10/15.
//

import Foundation
import UIKit

/// - MARK: 各种正则
enum Validation {
    /// 判断email
    case email(_: String)
    /// 判断手机号码
    case phoneNum(_: String)
    /// 判断车牌号码
    case carNum(_: String)
    /// 判断电话号码
    case telPhone(_: String)
    case telPhoneMustCros(_: String)
    case URL(_: String)
    case IP(_: String)
    
    /**
     * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>正则判断<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     * @"(^\\d{6}$)"                                                ******************         6位纯数字
     * @"^[0-9]{11}"                                                ******************         11位手机号
     * @"(^[A-Za-z0-9]{6,20}$)"                                     ****************** 6到20位数字字母组合
     * @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"          ******************            Email
     * @"(^[A-Za-z]+$)"        ^[A-Za-z\\s]+$                       ******************            纯字母
     * @"(^[1-9]\d*$)"                                              ******************            正整数
     * @"(^-[1-9]\d*$)"                                             ******************            负整数
     * @"(^-?[1-9]\d*$)"                                            ******************              整数
     * @"(^[1-9]\d*|0$)"                                            ******************           非负整数
     * @"(^-[1-9]\d*|0$)"                                           ******************           非正整数
     * @"(^-?([1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0)$)"             ******************             浮点数
     * @"(^[1-9]\d*\.\d*|0\.\d*[1-9]\d*|0?\.0+|0$)"                 ******************         非负浮点数
     * @"(^\\d{15}$)|(^\\d{17}([0-9]|X)$)"                          ******************         身份证号码
     * @"[1-9]\\d{5}(?!\\d)"                                        ******************           中国邮编
     * @"[\u4e00-\u9fa5]+"                                          ******************             全中文
     * @"^[\u4e00-\u9fa5]{1}[A-Z]{1}[A-Z_0-9]{5}$"                  ******************             车牌号
     *
     * @"^1(3[0-9]|5[0-35-9]|8[025-9])\\d{8}$";
     * @"^1(3[0-9]|5[0-35-9]|8[12378]|47)\\d{8}$";
     *
     * * 中国移动：China Mobile
     * * 134[0-8],135,136,137,138,139,150,151,157,158,159,182,187,188,1705
     * *
     * @"^1(34[0-8]|(3[5-9]|5[017-9]|8[278])\\d|70[5])\\d{7}$";
     * *
     * * 中国联通：China Unicom
     * * 130,131,132,152,155,156,185,186,1709
     * *
     * @"^1(70[9]|((3[0-2]|5[256]|8[56])\\d))\\d{7}$";
     * *
     * *中国电信：China Telecom
     * * 133,1349,153,180,181,189,1700
     * *
     * @"^1((33|53|8[0189])[0-9]|349|700)\\d{7}$";
     *
     * * 大陆地区固话及小灵通
     * * 区号：010,020,021,022,023,024,025,027,028,029
     * * 号码：七位或八位
     * *
     * @"^0(10|2[0-5789]|\\d{3})\\d{7,8}$";
     * >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>正则判断<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
     */
    var isRight: Bool {
        var predicateStr:String!
        var currObject:String!
        switch self {
        case let .email(str):
            predicateStr = "^([A-Za-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$"
            currObject = str
        case let .phoneNum(str):
            predicateStr = "^((13[0-9])|(15[0-9])|(17[0-9])|(18[0-9])|(14[0-9])|(16[0-9])|(19[0-9]))\\d{8}$"
            currObject = str
        case let .carNum(str):
            predicateStr = "^[A-Za-z]{1}[A-Za-z_0-9]{5}$"
            currObject = str
        case let .telPhone(str):
            predicateStr = "^(0\\d{2,3}-?\\d{7,8}$)"
            currObject = str
        case let .telPhoneMustCros(str):
            predicateStr = "^(0\\d{2,3}-\\d{7,8}$)"
            currObject = str
        case let .URL(str):
            predicateStr = "^(https?:\\/\\/)?([\\da-z\\.-]+)\\.([a-z\\.]{2,6})([\\/\\w \\.-]*)*\\/?$"
            currObject = str
        case let .IP(str):
            predicateStr = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"
            currObject = str
        }
        
        let predicate =  NSPredicate(format: "SELF MATCHES %@" ,predicateStr)
        return predicate.evaluate(with: currObject)
    }
    
    var isTelPhone: Bool {
        switch self {
        case let .telPhone(str):
            //带-的电话号码
            let predicateStr = "^(0\\d{2,3}-?\\d{7,8}$)"
            let predicate = NSPredicate(format: "SELF MATCHES %@", predicateStr)
            let isPhone = predicate.evaluate(with: str)
            //不带-的电话号码
            let predicateStr1 = "^(\\d{7,8}$)"
            let predicate1 = NSPredicate(format: "SELF MATCHES %@", predicateStr1)
            let isPhone1 = predicate1.evaluate(with: str)
            return isPhone || isPhone1
        default:
            return false
        }
        
    }
}

extension String {
    
    /// html文本转变成富文本 ps: 由于html格式的显示模式，一般在项目中统一，这里不开放相关参数
    var htmlToAttributedString: NSAttributedString? {
        guard let data = data(using: .utf8) else { return NSAttributedString() }
        do {
            let attrStr = try NSMutableAttributedString(data: data, options:
                                                            [.documentType: NSAttributedString.DocumentType.html,
                                                             .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
            /// 1、设置行间距
            let paraph = NSMutableParagraphStyle()
            paraph.lineSpacing = 5
            
            /// 2、设置Font
            let font = UIFont.systemFont(ofSize: 14)
            
            attrStr.addAttributes([
                NSAttributedString.Key.paragraphStyle: paraph,
                NSAttributedString.Key.font: font
            ], range: NSMakeRange(0, attrStr.length))
            
            /// 3、设置附件
            attrStr.enumerateAttribute(NSAttributedString.Key.attachment, in: NSRange(location: 0, length: attrStr.length), options: NSAttributedString.EnumerationOptions(rawValue: 0)) { (value, range, _) in
                
                if value != nil {
                    if let ment = value as? NSTextAttachment {
                        let originWidth = ment.bounds.size.width
                        let originHeight = ment.bounds.size.height
                        let SWidth = UIScreen.main.bounds.width

                        ment.bounds.size.width = originWidth > SWidth ? SWidth : originWidth
                        ment.bounds.size.height = originHeight
                    }
                }
            }
            
            return attrStr
        } catch  {
            return NSAttributedString()
        }
    }
    
    /// 给文本添加线
    /// - Parameters:
    ///     - text: 加线的文本
    ///     - type: NSAttributedString.Key 加线的类型，默认：中线---strikethroughStyle
    ///     - lineHeight: 线的高度，默认：1
    static func attributedAddLine(text: String,
                                  type: NSAttributedString.Key = .strikethroughStyle,
                                  lineHeight: Int = 1
    ) -> NSAttributedString {
        let tranformString = NSMutableAttributedString(string: text)
        /// 设置
        tranformString.addAttribute(type, value: NSNumber.init(value: lineHeight), range: NSRange(location: 0, length: text.count))
        
        return tranformString
    }
    
    /// 字典转Data
    static func jsonToData(jsonDic:Dictionary<String, Any>) -> Data? {

        if JSONSerialization.isValidJSONObject(jsonDic) == false { return nil }
        let data = try? JSONSerialization.data(withJSONObject: jsonDic, options: [])
        return data
    }
    
    /// 数组转Data
    static func arrayToData(paramArray: Array<Any>) -> Data? {
        if JSONSerialization.isValidJSONObject(paramArray) == false { return nil }
        let data = try? JSONSerialization.data(withJSONObject: paramArray, options: [])

        return data
    }
    
    /// 验证身份证
    func checkIdentityCardNumber(_ number: String) -> Bool {
        //判断位数
        if number.count != 15 && number.count != 18 {
            return false
        }
        var carid = number
        
        var lSumQT = 0
        
        //加权因子
        let R = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]
        
        //校验码
        let sChecker: [Int8] = [49,48,88, 57, 56, 55, 54, 53, 52, 51, 50]
        
        //将15位身份证号转换成18位
        let mString = NSMutableString.init(string: number)
        
        if number.count == 15 {
            mString.insert("19", at: 6)
            var p = 0
            let pid = mString.utf8String
            for i in 0...16 {
                let t = Int(pid![i])
                p += (t - 48) * R[i]
            }
            let o = p % 11
            let stringContent = NSString(format: "%c", sChecker[o])
            mString.insert(stringContent as String, at: mString.length)
            carid = mString as String
        }
        
        let cStartIndex = carid.startIndex
        let _ = carid.endIndex
        let index = carid.index(cStartIndex, offsetBy: 2)
        //判断地区码
        let sProvince = String(carid[cStartIndex..<index])
        if (!self.areaCodeAt(sProvince)) {
            return false
        }
        
        //判断年月日是否有效
        //年份
        let yStartIndex = carid.index(cStartIndex, offsetBy: 6)
        let yEndIndex = carid.index(yStartIndex, offsetBy: 4)
        let strYear = Int(carid[yStartIndex..<yEndIndex])
        
        //月份
        let mStartIndex = carid.index(yEndIndex, offsetBy: 0)
        let mEndIndex = carid.index(mStartIndex, offsetBy: 2)
        let strMonth = Int(carid[mStartIndex..<mEndIndex])
        
        //日
        let dStartIndex = carid.index(mEndIndex, offsetBy: 0)
        let dEndIndex = carid.index(dStartIndex, offsetBy: 2)
        let strDay = Int(carid[dStartIndex..<dEndIndex])
        
        let localZone = NSTimeZone.local
        
        let dateFormatter = DateFormatter()
        dateFormatter.dateStyle = .medium
        dateFormatter.timeStyle = .none
        dateFormatter.timeZone = localZone
        dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
        
        let date = dateFormatter.date(from: "\(String(format: "%02d",strYear!))-\(String(format: "%02d",strMonth!))-\(String(format: "%02d",strDay!)) 12:01:01")
        
        if date == nil {
            return false
        }
        let paperId = carid.utf8CString
        //检验长度
        if 18 != carid.count {
            return false
        }
        //校验数字
        func isDigit(c: Int) -> Bool {
            return 0 <= c && c <= 9
        }
        for i in 0...18 {
            let id = Int(paperId[i])
            if isDigit(c: id) && !(88 == id || 120 == id) && 17 == i {
                return false
            }
        }
        //验证最末的校验码
        for i in 0...16 {
            let v = Int(paperId[i])
            lSumQT += (v - 48) * R[i]
        }
        if sChecker[lSumQT%11] != paperId[17] {
            return false
        }
        return true
    }
    func areaCodeAt(_ code: String) -> Bool {
        var dic: [String: String] = [:]
        dic["11"] = "北京"
        dic["12"] = "天津"
        dic["13"] = "河北"
        dic["14"] = "山西"
        dic["15"] = "内蒙古"
        dic["21"] = "辽宁"
        dic["22"] = "吉林"
        dic["23"] = "黑龙江"
        dic["31"] = "上海"
        dic["32"] = "江苏"
        dic["33"] = "浙江"
        dic["34"] = "安徽"
        dic["35"] = "福建"
        dic["36"] = "江西"
        dic["37"] = "山东"
        dic["41"] = "河南"
        dic["42"] = "湖北"
        dic["43"] = "湖南"
        dic["44"] = "广东"
        dic["45"] = "广西"
        dic["46"] = "海南"
        dic["50"] = "重庆"
        dic["51"] = "四川"
        dic["52"] = "贵州"
        dic["53"] = "云南"
        dic["54"] = "西藏"
        dic["61"] = "陕西"
        dic["62"] = "甘肃"
        dic["63"] = "青海"
        dic["64"] = "宁夏"
        dic["65"] = "新疆"
        dic["71"] = "台湾"
        dic["81"] = "香港"
        dic["82"] = "澳门"
        dic["91"] = "国外"
        if (dic[code] == nil) {
            return false;
        }
        return true;
    }
}


